import Vue from 'vue'
import Vuex from 'vuex'
import router from '@/router'
import axios from 'axios'

import i18n from '@/i18n'

import localService from './service/locale'

// devices
import dept from './store/devices/dept'
import station from './store/devices/station'
import cu from './store/devices/cu'
import ccu from './store/devices/ccu'
import rcu from './store/devices/rcu'
import antenna from './store/devices/antenna'
import sessions from './store/devices/sessions'
import subscribeFreqSegment from './store/devices/subscribeFreqSegment'
import multicastFreqSegment from './store/devices/multicastFreqSegment'
import multicastReceiver from './store/devices/multicastReceiver'

// resources
import satellite from './store/resources/satellite'
import beam from './store/resources/beam'
import transponder from './store/resources/transponder'
import freqSegment from './store/resources/freqSegment'
import controlChannel from './store/resources/controlChannel'

// ncp
import usingCtrlChannel from './store/ncp/usingCtrlChannel'
import ctrlCount from './store/ncp/ctrlCount'
import channelUtility from './store/ncp/channelUtility'

// mtw
import cuLog from './store/mtw/cuLog'
import snrLog from './store/mtw/snrLog'

import ltlTree from './store/ltl/ltlTree'

import reconnectingWebSocket from './store/reconnectingWebSocket'

// parameters

import parameters from './store/parameters'

//  sam 
import samantenna from './store/sam/antenna'
import samnat from './store/sam/nat'
import samroute from './store/sam/router'
import samaccessterminal from './store/sam/accessterminal'
let bus = new Vue()

let vueI18n = new Vue({
  i18n
})

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    // devices
    dept,
    station,
    cu,
    ccu,
    rcu,
    antenna,
    sessions,
    subscribeFreqSegment,
    multicastFreqSegment,
    multicastReceiver,

    // resources
    satellite,
    beam,
    transponder,
    freqSegment,
    controlChannel,

    // ncp
    usingCtrlChannel,
    ctrlCount,
    channelUtility,

    // mtw
    cuLog,
    snrLog,

    // ltl
    ltlTree,

    // parameters
    parameters,
    // sam
    samantenna,
    samnat,
    samroute,
    samaccessterminal
  },
  plugins: [
    reconnectingWebSocket
  ],
  state: {
    userId: null,
    username: null,
    is_staff: false,

    webSocket: [],
    uid: '',
    networkContorlCenterName: '',
    selfNetworkUid: ''
  },
  mutations: {
    setUsername (state, data) {
      state.userId = data.id
      state.username = data.username
      state.is_staff = data.is_staff
    },
    receiveWebSocket (state, data) {
      state.webSocket.unshift(data)
    },
    setNetworkControlProgramUID (state, uid) {
      state.uid = uid
    },
    setNetworkContorlCenterName (state, name) {
      state.networkContorlCenterName = name
    },
    setSelfNetworkUid (state, uid) {
      state.selfNetworkUid = uid
    }
  },
  actions: {
    // 对axios模块的再封装
    async axios (context, { method = `get`, url, header = {}, data = null, params = null, proxy = true }) {
      let token = null
      // let locale = service.validateLocale(localStorage.getItem('locale'))
      let response = null
      const uid = context.state.uid
      // console.log(uid);
      let axiosUrl = url
      if (uid) {
        if (axiosUrl !== '/api/abs/auth/users/me/' && proxy === true) axiosUrl = `/api/abs/proxy/${uid}${axiosUrl}`
      }
      // 获取token
      try {
        token = await context.dispatch(`getTokenFromLocalstorage`)
      } catch (e) {
        if (axiosUrl === '/api/abs/auth/users/me/') { return null } else {
          // 用户信息失效,请重新登录
          bus.$message.error(vueI18n.$t('message.validate.store.message.msg1'))
          router.push('/login')
          throw new Error(e)
        }
      }
      // axios模块封装
      try {
        response = await axios({
          method: method,
          url: axiosUrl,
          headers: {
            ...header,
            Authorization: `JWT ${token}`,
            'Accept-Language': localService.validateLocale(localStorage.getItem('locale'))
          },
          params: params,
          data: data
        })
      } catch (e) {
        let message = ''
        switch (e.response.status) {
          case 500:
            // 服务器错误
            message = '服务器错误'
            break
          case 401:
            // 用户信息认证失败,请重新登录!
            message = vueI18n.$t('message.validate.store.message.msg2')
            localStorage.removeItem('token')
            router.push('/login')
            break
          case 400:
            // 如果返回的错误类型为字符串的话, 直接将其作为错误信息打印出来
            if (typeof (e.response.data) === 'string') {
              message = `<div>${e.response.data}</div>`
            } else {
              for (let key in e.response.data) {
                message += `<p>${e.response.data[key]}</p>`
              }
              message = `<div>${message}</div>`
            }
            break
          default:
            message = e.response.data
        }
        bus.$message({
          showClose: true,
          dangerouslyUseHTMLString: true,
          message: message,
          type: 'error'
        })
        return Promise.reject(e.response)
        // throw new Error(JSON.stringify(e.response.data))
      }
      return response
    },
    // 重新获取token并更新
    refreshToken (context, oldToken) {
      return new Promise((resolve, reject) => {
        axios.post(`/api/abs/auth/refresh/`, {
          token: oldToken
        })
          .then(result => {
            localStorage.setItem('token', result.data.token)
            resolve()
          })
          .catch(error => {
            console.log(error.data)
            reject(new Error('token error'))
          })
      })
    },
    // 从localstorage获得并返回token
    async getTokenFromLocalstorage (context) {
      let token = localStorage.getItem('token')
      let refreshTime = 1800 // 设置即将到期的最大时长
      // 判断token是否存在
      if (!token) {
        throw new Error('no token')
      }
      let timeNow = null
      let timeToken = null
      try {
        timeNow = parseInt(new Date().getTime() / 1000)
        timeToken = JSON.parse(window.atob(token.split('.')[1])).exp
      } catch (e) {
        throw new Error('token decoding error')
      }
      // 判断token是否过期
      let tokenTimeValidate = timeToken - timeNow
      // console.log(tokenTimeValidate)
      if (tokenTimeValidate < 0) {
        // token过期
        // 登录信息已失效,请重新登录
        bus.$message.error(vueI18n.$t('message.validate.store.message.msg3'))
        throw new Error('token out of time')
      } else if (tokenTimeValidate < refreshTime) {
        // token即将过期，刷新token
        await context.dispatch('refreshToken', token)
        return context.dispatch('getTokenFromLocalstorage')
      } else {
        // token未过期
        return token
      }
    },
    async getUserInfo (context) {
      try {
        console.log(123344566);
        let response = await context.dispatch(`axios`, {
          method: `get`,
          url: `/api/abs/auth/users/me/`
        })
        context.commit(`setUsername`, response.data)
        let path = window.location.href.split('#')[1].split('?')[0]
        console.log(path);
        if (path === '/login') {
          router.push('/home')
        }
        // 若访问的是子网控,则获取子网控的名称,以及本网控的UID
        console.log(context.state.uid);
        if (context.state.uid) {
          let networkContorlCenterName = JSON.parse(localStorage.getItem(context.state.uid)).name
          context.commit('setNetworkContorlCenterName', networkContorlCenterName)
        }
      } catch (e) {
        router.push('/login')
      }
    }
  }
})
